/* 
@author Huhaozhi 2022/2/7 
插槽: 
  inlineSearch 行内筛选
  tool 工具按钮 
  cols 表格列 
  extra 额外的操作按钮, 须配置isExtra为true 
  addItems 新增表单 
  editItems 编辑表单
*/
<template>
  <div class="w-full h-full myCurd">


    <HuBaseTable ref="table" v-bind="options">
      <template #inlineSearch="scoped">
        <slot name="inlineSearch" :searchModel="scoped.searchModel"></slot>
      </template>
      <template #tool="scoped">
        <el-form-item>
          <el-button v-if="isAdd" type="primary" @click="openAdd">新增</el-button>
        </el-form-item>

        <slot name="tool" :searchModel="scoped.searchModel"></slot>
      </template>
      <template #cols>
        <slot name="cols"></slot>
        <el-table-column v-if="isOperation" label="操作" fixed="right" width="300">
          <template #default="scoped">
            <el-button v-if="isEdit" type="primary" :icon="Edit" size="small" @click="openEdit(scoped.row)">编辑</el-button>
            <el-button v-if="isDel" type="danger" :icon="Delete" size="small" @click="openDel(scoped.row)">删除</el-button>
            <slot :name="isExtra ? 'extra' : 'remove_extra'" :row="scoped.row"></slot>
          </template>
        </el-table-column>
      </template>
    </HuBaseTable>

    <!-- 新增 -->
    <el-dialog v-model="addModel.show" :title="addTitle" :width="dialogWidth">
      <el-form ref="addForm" :rules="addRules" :model="addModel.model" :label-width="labelWidth">
        <slot :name="isAdd ? 'addItems' : 'remove_addItems'" :addModel="addModel.model"></slot>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancel">{{ cancelBtnText }}</el-button>
          <el-button type="primary" @click="submitAdd(addForm)" :loading="addModel.loading">{{
            comfirmBtnText
          }}</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 编辑 -->
    <el-dialog v-model="editModel.show" :title="editTitle" :width="dialogWidth">
      <el-form ref="editForm" :rules="editRules" :model="editModel.model" :label-width="labelWidth">
        <slot :name="isEdit ? 'editItems' : 'remove_editItems'" :editModel="editModel.model"></slot>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancel">{{ cancelBtnText }}</el-button>
          <el-button type="primary" @click="submitEdit(editForm)" :loading="editModel.loading">{{
            comfirmBtnText
          }}</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 删除 -->
    <el-dialog v-model="delModel.show" :title="delTitle" :width="delDialogWidth">
      <span style="font-size: 16px">{{ delContent }}</span>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancel">{{ cancelBtnText }}</el-button>
          <el-button type="primary" @click="submitDel" :loading="delModel.loading">{{ comfirmBtnText }}</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import HuBaseTable from "./HubasicTable.vue";
import { Edit, Delete } from "@element-plus/icons-vue";
import { reactive, ref, computed, useSlots } from "vue";
import type { ElForm } from "element-plus";
import { ElMessage } from 'element-plus'

const props = defineProps({
  api: {
    type: Object,
    default: () => ({}),
  },
  keys: {
    type: String,
    default: "id",
  },
  isKeyword: {
    type: Boolean,
    default: false
  },
  labelWidth: {
    type: String,
    default: "80px",
  },
  addRules: {
    type: Object,
    default: () => ({}),
  },
  editRules: {
    type: Object,
    default: () => ({}),
  },
  dialogWidth: {
    type: String,
    default: "700px",
  },
  delDialogWidth: {
    type: String,
    default: "400px",
  },
  isAdd: {
    type: Boolean,
    default: false,
  },
  addTitle: {
    type: String,
    default: "新增",
  },
  isEdit: {
    type: Boolean,
    default: false,
  },
  editTitle: {
    type: String,
    default: "编辑",
  },
  editDefaultParams: {
    type: Object,
    default: () => ({}),
  },
  isDel: {
    type: Boolean,
    default: false,
  },
  delTitle: {
    type: String,
    default: "删除",
  },
  delContent: {
    type: String,
    default: "确定要删除该数据吗? ",
  },
  isExtra: {
    type: Boolean,
    default: false,
  },
  comfirmBtnText: {
    type: String,
    default: "确认",
  },
  cancelBtnText: {
    type: String,
    default: "取消",
  },
  isBread: {
    type: Boolean,
    default: false
  },
  total: {
    type: String,
    default: 'total'
  },
  addExtraProps: {
    type: Object,
    default: () => ({})
  },
  editExtraProps: {
    type: Object,
    default: () => ({})
  },
  listKey: {
    type: String,
    default: 'list'
  },
  isSearch: {
    type: Boolean,
    default: true
  },
  beforeLoadData: {
    type: Function
  },
  beforeAdd: {
    type: Function
  },
  beforeEdit: {
    type: Function
  },
  list: {
    type: Boolean,
    default: false
  }
});
interface Model {
  [propsName: string]: any;
}
const {
  api,
  keys,
  editDefaultParams,
  isKeyword,
  isEdit,
  isDel,
  isExtra,
  isBread,
  total,
  addExtraProps,
  editExtraProps,
  listKey,
  isSearch,
  beforeLoadData,
  beforeAdd,
  beforeEdit,
  list
} = props;
const slot = useSlots();
/* base组件指针 */
const table = ref();
/* 新增表单指针 */
const addForm = ref();
/* 编辑表单指针 */
const editForm = ref();
/* 表单类型指明 */
type FormInstance = InstanceType<typeof ElForm>;
const options = reactive({
  api,
  isKeyword,
  isBread,
  total,
  listKey,
  isSearch,
  beforeLoadData,
  beforeAdd,
  beforeEdit,
  list
});
const addModel: Model = reactive({
  show: false,
  loading: false,
  model: {
    ...addExtraProps
  },
});
const editModel: Model = reactive({
  id: "",
  show: false,
  loading: false,
  model: {
    ...editExtraProps
  },
});
const delModel: Record<string, any> = reactive({
  id: "",
  show: false,
  loading: false,
});

/* 计算属性 */
const isOperation = computed(() => {
  if (isEdit || isDel) {
    return true
  }
  if (slot.extra && isExtra) {
    return true
  }
  return false
})
/* 方法 */
function openAdd(): void {
  addModel.show = true;
}
function submitAdd(form: FormInstance | undefined): void {
  if (!form) {
    return;
  }
  form.validate((v: any) => {
    if (v) {
      addModel.loading = true;
      let resultAdd = {}
      if (beforeAdd) {
        resultAdd = beforeAdd(addModel.model)
      } else {
        resultAdd = addModel.model
      }
      api.add(resultAdd).then(() => {
        ElMessage.success('操作成功')
        table.value.loadData().then(() => {
          addModel.loading = false;
          addModel.show = false;
          addModel.model = {}
        });
      });
    }
  });
}
function openEdit(row: any): void {
  editModel[keys] = row[keys];
  console.log()
  editModel.model = Object.assign({}, editModel.model, row, editDefaultParams);
  editModel.show = true;
}
function submitEdit(form: FormInstance | undefined): void {
  if (!form) {
    return;
  }
  form.validate((v) => {
    if (v) {
      editModel.loading = true;
      let resultEdit = {}
      if (beforeEdit) {
        resultEdit = beforeEdit(editModel.model)
      } else {
        resultEdit = editModel.model
      }
      console.log(editModel, 'edit')
      api.edit(editModel[keys], resultEdit).then(() => {
        ElMessage.success('操作成功')
        table.value.loadData().then(() => {
          editModel.loading = false;
          editModel.show = false;
          editModel.model = {}
        });
      });
    }
  });
}
function openDel(row: any): void {
  delModel[keys] = row[keys];
  delModel.show = true;
}
function submitDel(): void {
  delModel.loading = true;
  api.del(delModel[keys]).then(() => {
    table.value.loadData().then(() => {
      delModel.loading = false;
      delModel.show = false;
    });
  });
}
function cancel(): void {
  addModel.show = false;
  editModel.show = false;
  delModel.show = false;
  addModel.model = {}
  editModel.model = {}
}
function getData() {
  table.value.loadData()
}

defineExpose({
  getData
})
</script>

<style scoped>
.myCurd {
  background-color: #fff;
}
</style>